package org.redmagic.service.utils;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.transform;

import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

import org.redmagic.domain.Property;
import org.redmagic.service.domain.ui.DisplayProperty;
import org.redmagic.service.domain.ui.Tag;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;

@ParametersAreNonnullByDefault
public final class RedMagicProperties {
	
	public static Property toProperty(DisplayProperty displayProperty) {
		Property.Builder builder = new Property.Builder(displayProperty.getName()).withValue(displayProperty.getValue());
		// remove any empty or null values and sort
		SortedSet<String> sortedTagValues = Sets.filter(new TreeSet<String>(displayProperty.getTagNames()), NON_EMPTY_FILTER);
		Iterator<String> iter = sortedTagValues.iterator();
		while (iter.hasNext()) {
			builder.withTag(iter.next());
		}
		
		return builder.build();
	}
	
	public static DisplayProperty toDisplayProperty(Property property) {
		if (property.getTags().isEmpty()) {
			property.getTags().add("");
		}
		DisplayProperty propertyForm = new DisplayProperty(transform(property.getTags(), TO_TAG_FUNCTION));
		propertyForm.setName(property.getName());
		propertyForm.setValue(property.getValue());
		return propertyForm;
	}
	
	public static final Predicate<String> NON_EMPTY_FILTER = new Predicate<String>() {
		
		@Override
		public boolean apply(String tag) {
			return !Strings.isNullOrEmpty(tag);
		}
	};
	
	public static final Function<String,Tag> TO_TAG_FUNCTION = new Function<String, Tag>() {

		@Override
		@Nullable
		public Tag apply(@Nullable String value) {
			return new Tag(value);
		}
		
	};
	
	public static final Function<Tag,String> TAG_VALUE_FUNCTION = new Function<Tag, String>() {

		@Override
		@Nullable
		public String apply(@Nullable Tag tag) {
			checkNotNull(tag, "tag");
			return tag.getValue();
		}
		
	};
}